


// React 组件生命周期 
// react 组件生命周期
// 组件的生命周期  (https://segmentfault.com/a/1190000016617400?utm_source=tag-newest)
/*
 react 组件的生命周期
 含义   组件从初始化渲染到被移除或者销毁的过程  成为组件的生命周期

 1. 每个组件都有生命周期
 2. react 通过组件的生命周期钩子函数来管理 组件
 3. 系统 某些状态和参数发生改变的时候，系统立马去通知 对应处理的函数叫做钩子函数
 hooks 钩子函数  允许在特定的时期添加用户自己的代码  不同的阶段添加自己的逻辑代码  (作用)


 react 组件的生命周期 分为三个阶段 
 1.mount  组件的初始化  从虚拟DOM 渲染成为真实DOM 的过程    1  
 2.update   组件的数据变化 setState  组件的state 更新 导致二次渲染的过程     n  
 3.unmount  组件销毁   组件因为路由切换而销毁 (浏览器的垃圾回收机制 )     1  




 mounted 组件载入阶段  (钩子函数  15 16 17 18) 
 0.constructor   class 构造器函数  纯函数组件没有  不是生命周期钩子函数 
 1.getDefaultProps   设置组件默认的props   废弃 16已经被废弃   App.defaultPorps    15 
 2.getInitialState   设置组件默认的state   废弃 16已经被废弃   this.state state = {}  15 
 3.componentWillMount  在jsx被渲染到页面之前被调用  废弃 16尚存  17警告  18废弃 
 3.1  getDerivedStateFromProps ( 组件每次被rerender的时候，包括在组件构建之后(虚拟dom之后，实际dom挂载之前)，每次获取新的props或state之后；;每次接收新的props之后都会返回一个对象作为新的state，返回null则说明不需要更新state)   17新增的 
 4.render   渲染函数是react中默认的函数  虚拟DOM 正在渲染成真实DOM  (虚拟DOM 渲染成 真实DOM 的函数 )
 5.componentDidMount   jsx被渲染到页面后被调用   1    已经全部都是真是DOM  实例化    99.999999  (虚拟DOM 已经渲染成为真实DOM )
 
*/ 
/*
update 组件数据更新阶段  setState  组件修改 state  组件接收的props发送改变  都会进入 update 阶段 
1. componentWillReceiveProps(nextProps)  接收变化的props   废弃 16尚存  17警告   18废弃
2.1 getDerivedStateFromProps  获取最新的state 从 props 
2. shouldComponentUpdate  询问是否更新  true 更新 false 不更新   性能优化  SCU机制
3. componentWillUpdate ==>     组件即将更新之前    废弃 16尚存  17警告 18废弃   
4. render   组件开始二次渲染  update  
4.1 getSnapshotBeforeUpdate  组件更新之前触发 得到旧的props和state    17新增 
5. componentDidUpdate   组件更新渲染数据完毕 

*/ 
// unMount 组件销毁移除 路由切换 
// componentDidCatch     捕获异常 
// componentWillUnmount  这个函数几乎不会使用到，因为浏览器本身具有垃圾回收机制  清除计时器 

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import MyBtn from './MyBtn';



class MyLife extends Component {
    state = {
        flag :true 
    }
    render() {
        const {flag } = this.state;
        return (
            <div>
                <h3>React 组件生命周期 </h3>
                <hr/>
                {
                    flag && <MyChild msg="wh2217 yyds" ></MyChild>
                }
                <MyBtn text="销毁子组件" onClick={ ()=>this.setState({flag:!flag}) }></MyBtn>
            </div>
        );
    }

    componentDidMount(){
        console.log("这是父组件的 初始化载入 ")
    }
}

let index = 0;
class MyChild extends Component{

    constructor(){
        super()
        this.log('constructor - 构造函数初始化')
    }
    // 这三个被废弃了
    // componentWillMount(){
    //     this.log('componentWillMount - 即将载入')
    // }

    // componentWillReceiveProps(){
    //     this.log("componentWillReceiveProps 接受最新的props ")
    // }

    // componentWillUpdate(){
    //     this.log('componentWillUpdate')
    // }
    // static 静态函数
    // 没有this undefined 
    static getDerivedStateFromProps(props,state){
        console.log(props)
        console.log(state)
        // this.log("getDerivedStateFromProps")
        console.log(` #${++index} --- ${'getDerivedStateFromProps 获取新的state从props '}`)
        return {
            a:1000,
            ...props
        }   // 返回的数据会合并到 state 
    }

    log=(msg)=>{
        console.log(` #${++index} --- ${msg}`)
    }

    state = {
        count:2000,
        word:"Are you OK"
    }
    change=()=>{
        this.setState({
            count:this.state.count+1
        })
    }

    // SCU优化  性能优化 
    shouldComponentUpdate(props,state){
        console.log(props,state)   // 新值 
        console.log(this.props , this.state) // 旧值 
        this.log('shouldComponentUpdate - 询问是否可以更新')
        if(this.state.word != state.word){   // 性能优化 
            return true;
        }else{
            return false 
        }
        // return true ;
    }


    render(){
        console.log(this)
        this.log('redner = 组件正在渲染')
        const {count, word } = this.state;
        return (
            <div>
                <h2>MyChild - 1 - 测试生命周期  </h2>
                <h3 > count = {count} </h3>
                <h3> word= {word } </h3>
                <hr/>
                <MyBtn text="change " onClick={this.change}></MyBtn>
                <p>
                    <input type="text" ref={el=>this.one=el} value={word} onChange={  ()=>this.setState({word: this.one.value})  } />
                </p>
            </div>
        )
    }
    
    // 获取修改之前的旧数据
    getSnapshotBeforeUpdate(props,state){
        console.log(props,state)  // 旧值  
        console.log(this.props,this.state)  // 新值  
        this.log('getSnapshotBeforeUpdate - 获取修改之前的旧数据')
        return {
            b:888,
            ...state
            // ...this.state

        }
    }

    

    componentDidUpdate(props,state,oldState){
        console.log(props,state,oldState)
        this.log('componentDidUpdate - 组件已经二次更新完毕')
    }

    // 最重要
    componentDidMount(){
        // 插件实例化 new Swiper  new echarts.init()
        // 请求ajax 
        this.log('componentDidMount - 组件初始化载入')
    }

    componentWillUnmount(){
        this.log('componentWillUnmount - 组件销毁了 ')
    }
}





export default MyLife;
